﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using GeoAPI.Geometries;
using YJKRevitDimensionText.VerticalAutoDim.Comparer;
using YJKRevitDimensionText.VerticalAutoDim.GeoAlgorithm;
using YJKRevitDimensionText.VerticalAutoDim.GeoModel;
using YJKGridTopologyCal.Index.Quadtree;

namespace YJKRevitDimensionText.VerticalAutoDim.Group
{
	internal class GeoVerticalSearch
	{
		public GeoVerticalSearch(IList<List<IPlanarGeo>> arrayWindDoorGeoSortedByLevel, double dElevMinEcs, double dElevMaxEcs)
		{
			this.ArrayWindDoorGeoSortedByLevel = arrayWindDoorGeoSortedByLevel;
			this.ElevMin = dElevMinEcs;
			this.ElevMax = dElevMaxEcs;
		}

		public IList<GeoVerticalDimResult> Calc()
		{
			IList<GeoVerticalDimResult> list = new List<GeoVerticalDimResult>();
			Quadtree<GeoAABB> quadtree = new Quadtree<GeoAABB>();
			List<List<GeoAABB>> list2 = new List<List<GeoAABB>>();
			int count = this.ArrayWindDoorGeoSortedByLevel.Count;
			for (int i = 0; i < count; i++)
			{
				List<IPlanarGeo> list3 = this.ArrayWindDoorGeoSortedByLevel[i];
				list3.Sort(new GeoComparerByTopLevel(false));
				list3.Sort(new GeoComparerAtEqualLevel(true));
				List<GeoAABB> list4 = new List<GeoAABB>(list3.Count);
				foreach (IPlanarGeo iPlanarGeo in list3)
				{
					GeoAABB geoAABB = new GeoAABB(iPlanarGeo, new GeoGroupLevelData
					{
						IsValid = true,
						LevelIndex = i
					});
					quadtree.Insert(geoAABB.AABB, geoAABB);
					list4.Add(geoAABB);
				}
				list2.Add(list4);
			}
			double num = 0.0032808398950131233;
			for (int j = 0; j < count; j++)
			{
				foreach (GeoAABB geoAABB2 in list2[j])
				{
					GeoGroupLevelData geoGroupLevelData = geoAABB2.Data as GeoGroupLevelData;
					if (geoGroupLevelData.IsValid)
					{
						List<GeoAABB> list5 = new List<GeoAABB>();
						list5.Add(geoAABB2);
						Envelope envelope = new Envelope(geoAABB2.IPlanarGeo.Min2DPointECS.X, geoAABB2.IPlanarGeo.Max2DPointECS.X, this.ElevMin, this.ElevMax);
						IList<GeoAABB> list6 = quadtree.Query(envelope);
						if (list6.Count != 0)
						{
							new GeoVerticalDimResult();
							XYZ xyz = new XYZ(geoAABB2.IPlanarGeo.Min2DPointECS.X, this.ElevMin, geoAABB2.IPlanarGeo.Min2DPointECS.Z);
							XYZ xyz2 = new XYZ(geoAABB2.IPlanarGeo.Max2DPointECS.X, this.ElevMax, geoAABB2.IPlanarGeo.Max2DPointECS.Z);
							Outline outline = new Outline(xyz, xyz2);
							foreach (GeoAABB geoAABB3 in list6)
							{
								if (geoAABB3 != geoAABB2)
								{
									GeoGroupLevelData geoGroupLevelData2 = geoAABB3.Data as GeoGroupLevelData;
									if (geoGroupLevelData2.IsValid)
									{
										Outline outline2 = new Outline(geoAABB3.IPlanarGeo.Min2DPointECS, geoAABB3.IPlanarGeo.Max2DPointECS);
										if (outline.Intersects(outline2, num))
										{
											if (Math.Abs(geoGroupLevelData2.LevelIndex - geoGroupLevelData.LevelIndex) <= 1)
											{
												list5.Add(geoAABB3);
											}
											else
											{
												using (List<GeoAABB>.Enumerator enumerator4 = list5.GetEnumerator())
												{
													while (enumerator4.MoveNext())
													{
														if (Math.Abs((enumerator4.Current.Data as GeoGroupLevelData).LevelIndex - geoGroupLevelData2.LevelIndex) <= 1)
														{
															list5.Add(geoAABB3);
															break;
														}
													}
												}
											}
										}
									}
								}
							}
							GeoVerticalDimResult resultTmp = new GeoVerticalDimResult();
							list5.ForEach(delegate(GeoAABB g)
							{
								resultTmp.ArrayGeo.Add(g.IPlanarGeo);
								(g.Data as GeoGroupLevelData).IsValid = false;
							});
							resultTmp.ArrayGeo.Sort(new GeoComparerByTopLevel(false));
							list.Add(resultTmp);
						}
					}
				}
			}
			return list;
		}

		private readonly IList<List<IPlanarGeo>> ArrayWindDoorGeoSortedByLevel;

		private readonly double ElevMin;

		private readonly double ElevMax;
	}
}
